const path = require('path');

// 文件导入器类
class DataImporter {
  constructor() {
    this.parsers = {
      'csv': this.parseCSV.bind(this),
      'xlsx': this.parseExcel.bind(this),
      'xls': this.parseExcel.bind(this),
      'json': this.parseJSON.bind(this),
      'case': this.parseCaseFile.bind(this)
    };
  }

  // 预览数据
  async previewData(dataType, filePath) {
    try {
      if (!filePath) {
        throw new Error('未选择文件');
      }

      // 获取文件扩展名
      const extension = path.extname(filePath).toLowerCase().substring(1);
      if (!this.parsers[extension]) {
        throw new Error(`不支持的文件格式: ${extension}`);
      }

      // 解析文件
      const parsedData = await this.parsers[extension](filePath);

      // 只返回前几条记录用于预览
      const previewData = parsedData.slice(0, 10); // 只取前10条用于预览

      // 获取所有可用的字段名
      const availableFields = this.getAvailableFields(previewData);

      // 获取目标字段映射
      const targetFields = this.getTargetFields(dataType);

      return {
        success: true,
        previewData: previewData,
        availableFields: availableFields,
        targetFields: targetFields,
        totalRecords: parsedData.length,
        fullData: parsedData // 返回完整数据以便后续处理，注意大数据量传输性能
      };
    } catch (error) {
      console.error(`预览${dataType}数据失败:`, error);
      return {
        success: false,
        message: error.message
      };
    }
  }

  // 获取可用字段
  getAvailableFields(data) {
    if (!data || data.length === 0) return [];

    const fieldsSet = new Set();
    data.forEach(row => {
      Object.keys(row).forEach(key => {
        fieldsSet.add(key);
      });
    });

    return Array.from(fieldsSet);
  }

  // 获取目标字段
  getTargetFields(dataType) {
    const fieldMappings = {
      bank: {
        transaction_time: '交易时间',
        account_number: '账户号',
        counterparty_account: '对方账户',
        transaction_amount: '交易金额',
        transaction_type: '交易类型',
        balance_after: '交易后余额',
        remarks: '备注'
      },
      call: {
        user_name: '机主姓名',
        user_id: '用户标识',
        user_number: '本机号码',
        imsi: '国际移动用户识别码',
        opp_user_number: '对方号码',
        a_number: '主叫号码',
        start_time: '通话开始时间',
        duration: '通话时长',
        call_type: '呼叫类型',
        lac_id: '位置区编码',
        cell_id: '小区标识',
        esn: '电子序列号',
        hplmn2: '归属公共陆地移动网络',
        vplmn2: '拜访公共陆地移动网络',
        opp_roam_areacode: '对方漫游地区号',
        opp_home_areacode: '对方归属地区号'
      },
      travel: {
        start_time: '开始时间',
        end_time: '结束时间',
        origin: '出发地',
        destination: '目的地',
        transport_type: '交通工具'
      },
      accommodation: {
        guest_name: '姓名',
        id_number: '身份证号',
        certificate_number: '证件号码',
        check_in_time: '入住时间',
        check_out_time: '离店时间',
        hotel_name: '旅店名称',
        room_number: '房间号码',
        hotel_district: '旅店区划',
        hotel_address: '旅店地址',
        certificate_type: '证件类型',
        nationality: '国籍/地区',
        gender: '性别',
        ethnicity: '民族',
        birth_date: '出生日期',
        household_district: '户籍地区划',
        household_address: '户籍地详址'
      },
      property: {
        feedback_unit: '反馈单位',
        approval_form: '审批表',
        owner_name: '名称',
        certificate_type: '证件类型',
        certificate_number: '证件号码',
        property_unit_number: '不动产单元号',
        property_address: '房地坐落',
        building_area: '建筑面积',
        planning_purpose: '规划用途',
        property_nature: '房屋性质',
        completion_date: '竣工时间',
        land_use_start_date: '土地使用起始时间',
        land_use_end_date: '土地使用结束时间',
        property_certificate_number: '不动产权证号',
        registration_authority: '登记机构'
      },
      railway: {
        passenger_name: '姓名',
        id_number: '身份证号',
        certificate_number: '证件号码',
        train_number: '车号',
        departure_date: '发车日期',
        departure_station: '发站',
        arrival_station: '到站',
        carriage_number: '车厢号',
        seat_number: '座位号',
        ticket_number: '票号',
        ticket_status: '车票状态',
        certificate_type: '证件类型'
      },
      flight: {
        passenger_chinese_name: '旅客中文姓名',
        id_number: '身份证号',
        certificate_number: '证件号码',
        flight_date: '航班日期',
        departure_port: '起飞港站',
        arrival_port: '到达航站',
        airline_company: '航空公司',
        flight_number: '航班号',
        gender: '性别',
        birth_date: '出生日期',
        certificate_type: '证件类型',
        seat_number: '旅客座位',
        departure_time: '离港时间',
        arrival_time: '进港时间'
      },
      business: {
        feedback_unit: '反馈单位',
        approval_form: '审批表',
        name: '名称',
        certificate_type: '证件类型',
        certificate_number: '证件号码',
        unified_social_credit_code: '统一社会信用代码',
        enterprise_name: '企业名称',
        legal_representative: '法定代表人',
        registration_number: '注册号',
        market_entity_type: '市场主体类型',
        establishment_date: '成立日期',
        registration_authority: '登记机关',
        business_scope: '经营范围',
        registration_status: '登记状态',
        address: '住所',
        registered_capital: '注册资本'
      }
    };

    return fieldMappings[dataType] || {};
  }

  // 应用字段映射
  applyFieldMapping(data, fieldMapping) {
    return data.map(row => {
      const newRow = {};
      for (const [targetField, sourceField] of Object.entries(fieldMapping)) {
        if (sourceField && row[sourceField] !== undefined) {
          newRow[targetField] = row[sourceField];
        }
      }
      return newRow;
    });
  }

  // CSV文件解析
  async parseCSV(filePath) {
    return new Promise((resolve, reject) => {
      const fs = require('fs');
      const csv = require('csv-parser');
      const results = [];
      const readStream = fs.createReadStream(filePath);

      readStream
        .pipe(csv())
        .on('data', (data) => results.push(data))
        .on('end', () => resolve(results))
        .on('error', reject);
    });
  }

  // Excel文件解析
  async parseExcel(filePath) {
    const ExcelJS = require('exceljs');
    const workbook = new ExcelJS.Workbook();

    try {
      await workbook.xlsx.readFile(filePath);

      // 更健壮的工作表获取逻辑
      let worksheet = null;

      // 方法1: 尝试获取第一个工作表（索引1）
      worksheet = workbook.getWorksheet(1);

      // 方法2: 如果失败，尝试索引0
      if (!worksheet) {
        worksheet = workbook.getWorksheet(0);
      }

      // 方法3: 如果仍失败，遍历所有工作表找到第一个可见的
      if (!worksheet && workbook.worksheets && workbook.worksheets.length > 0) {
        worksheet = workbook.worksheets.find(ws => ws.state === 'visible') || workbook.worksheets[0];
      }

      // 方法4: 使用 eachSheet 遍历
      if (!worksheet) {
        workbook.eachSheet((sheet) => {
          if (!worksheet) {
            worksheet = sheet;
          }
        });
      }

      if (!worksheet) {
        throw new Error('Excel文件中没有工作表或工作表无法读取');
      }

      const results = [];
      let headers = [];

      // 读取表头（第一行）
      if (worksheet.rowCount >= 1) {
        const headerRow = worksheet.getRow(1);

        // 增强表头解析：处理富文本、公式等对象类型
        headers = headerRow.values.slice(1).map(val => {
          if (val && typeof val === 'object') {
            if (val.text !== undefined) return val.text;
            if (val.richText) return val.richText.map(t => t.text).join('');
            if (val.result !== undefined) return String(val.result);
            return String(val);
          }
          return val !== undefined && val !== null ? String(val) : '';
        });

        // 遍历数据行（从第2行开始）
        for (let i = 2; i <= worksheet.rowCount; i++) {
          const row = worksheet.getRow(i);
          const rowData = {};

          for (let j = 0; j < headers.length; j++) {
            const cellValue = row.getCell(j + 1).value;
            // 处理不同类型的单元格值
            if (cellValue && typeof cellValue === 'object' && !(cellValue instanceof Date)) {
              if (cellValue.text !== undefined) {
                rowData[headers[j]] = cellValue.text;
              } else if (cellValue.result !== undefined) {
                rowData[headers[j]] = cellValue.result;
              } else if (cellValue.richText) {
                rowData[headers[j]] = cellValue.richText.map(t => t.text).join('');
              } else if (cellValue.formula) {
                rowData[headers[j]] = cellValue.result !== undefined ? cellValue.result : cellValue;
              } else {
                rowData[headers[j]] = cellValue;
              }
            } else {
              rowData[headers[j]] = cellValue;
            }
          }

          results.push(rowData);
        }
      }

      return results;
    } catch (error) {
      console.error('解析Excel文件失败:', error);
      throw error;
    }
  }

  // JSON文件解析
  async parseJSON(filePath) {
    const fs = require('fs').promises;
    const fileContent = await fs.readFile(filePath, 'utf8');

    try {
      const jsonData = JSON.parse(fileContent);

      // 如果是对象数组，直接返回
      if (Array.isArray(jsonData)) {
        return jsonData;
      }

      // 如果是对象，检查是否有数据数组
      if (typeof jsonData === 'object' && jsonData.data) {
        return Array.isArray(jsonData.data) ? jsonData.data : [jsonData.data];
      }

      // 如果是单个对象，包装成数组
      return [jsonData];
    } catch (error) {
      throw new Error('JSON文件格式错误');
    }
  }

  // Case文件解析
  async parseCaseFile(filePath) {
    throw new Error('Case文件解析功能需在主进程中处理');
  }

  // 数据验证方法
  async validateData(dataType, rawData) {
    if (!Array.isArray(rawData)) {
      throw new Error('解析后的数据格式错误，应为数组格式');
    }

    // 根据数据类型验证必要字段
    const fieldMappings = {
      bank: {
        required: ['transaction_time', 'account_number', 'transaction_amount'],
        optional: ['counterparty_account', 'transaction_type', 'balance_after', 'remarks']
      },
      call: {
        required: ['start_time', 'user_number'],
        optional: ['opp_user_number', 'duration', 'call_type']
      },
      travel: {
        required: ['start_time', 'origin', 'destination'],
        optional: ['end_time', 'transport_type']
      },
      accommodation: {
        required: ['guest_name', 'hotel_name'],
        optional: ['check_in_time', 'check_out_time', 'room_number', 'id_number']
      },
      property: {
        required: ['property_address', 'owner_name'],
        optional: ['building_area', 'property_certificate_number']
      },
      railway: {
        required: ['passenger_name', 'train_number'],
        optional: ['departure_station', 'arrival_station', 'departure_date', 'id_number']
      },
      flight: {
        required: ['passenger_chinese_name', 'flight_number'],
        optional: ['departure_port', 'arrival_port', 'flight_date', 'id_number']
      },
      business: {
        required: ['enterprise_name'],
        optional: ['unified_social_credit_code', 'legal_representative', 'registration_number']
      }
    };

    const validationConfig = fieldMappings[dataType];
    if (!validationConfig) {
      throw new Error(`未知的数据类型: ${dataType}`);
    }

    // 检查必要字段是否存在
    const validatedData = rawData.map((item, index) => {
      // 检查必要字段
      for (const field of validationConfig.required) {
        if (!(field in item) || item[field] === undefined || item[field] === null) {
          console.warn(`警告: 第${index + 1}行缺少必要字段 ${field}`);
        }
      }

      return item;
    });

    return validatedData;
  }

  // 获取数据类型名称
  getDataTypeName(dataType) {
    const names = {
      'bank': '银行流水',
      'call': '通话单',
      'travel': '出行记录',
      'accommodation': '住宿记录',
      'property': '不动产'
    };
    return names[dataType] || dataType;
  }
}

module.exports = DataImporter;